/* UTF8 Encoding */
/*-----------------------------------------------------------------------
|                            FILE DESCRIPTION                           |
-----------------------------------------------------------------------*/
/*----------------------------------------------------------------------
  - File name     : cReceive.hpp
  - Author        : liuzhihua (liuzhihuawy@163.com)
  - Update date   : 2024.03.09
  - Brief         : data receive
  - Version       : v0.1
-----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------
|                               UPDATE NOTE                             |
-----------------------------------------------------------------------*/
/**
  * Update note:
  * ------------   ---------------   ----------------------------------
  *     Date            Author                      Note
  * ------------   ---------------   ----------------------------------
  *  2024.03.01       liuzhihua                  Create file          
***/

#ifndef CRECEIVE_H
#define CRECEIVE_H

/*-----------------------------------------------------------------------
|                               INCLUDES                                |
-----------------------------------------------------------------------*/
#include <stdint.h>
#include "cQueue.h"
/*-----------------------------------------------------------------------
|                                DEFINES                                |
-----------------------------------------------------------------------*/
#define CRECEIVE_TIMEOUT_ENABLE 0

/*-----------------------------------------------------------------------
|                                 CLASS                                 |
-----------------------------------------------------------------------*/

class cReceive
{
    private:
        cQueue_t dataQueue;  // data queue
        cQueue_t cntQueue;  // cnt queue
        uint16_t transferSize; // Size waiting for transfer
        uint16_t endIndex;
        const uint16_t frameMaxSize;
        enum receive_state_e
        {
            STATE_IDLE,
            STATE_READY,
            STATE_BUSY,
            STATE_DONE,
            STATE_TIMEOUT,
            STATE_FULL,
            STATE_ERROR
        } state;

#if !!(CRECEIVE_TIMEOUT_ENABLE)
        uint32_t (*get_time)(void);
        uint32_t time_limit;
        uint32_t time_last;
#endif

    public:
        cReceive(uint8_t *pDataBuffer,
                 uint16_t dataBufferSize,
                 uint16_t frameMaxSize,
                 uint16_t counterSize);
                 
        ~cReceive();
#if !!(CRECEIVE_TIMEOUT_ENABLE)
        void pack_time_init(uint32_t (*get_time_callback)(void), uint32_t time_limit);
#endif
        uint16_t getMaxFrameSize(void);
        bool isEmpty(void);
        bool isFull(void);
        bool push(uint8_t* &pData, uint16_t dataSize);
        uint8_t *push_start(uint16_t dataSize);

        int pop(uint8_t* &pData, uint16_t bufSize);
        void clear(void);
        int receiveDone_callback(void);
};

/*-----------------------------------------------------------------------
|                                  API                                  |
-----------------------------------------------------------------------*/
#ifdef  __cplusplus
    extern "C" {
#endif

#ifdef __cplusplus
	}
#endif
#endif
